﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.Media;
using Microsoft.Phone.Tasks;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Resources;
using ExifLib;
using System.Windows.Threading;
using System.Threading;
using Coding4Fun.Toolkit.Controls;
using Microsoft.Phone.Shell;

namespace BigPicWatcher
{
    public partial class PageMode1 : PhoneApplicationPage
    {
        double _zoom;
        //当前缩放
        double Zoom
        {
            get { return _zoom; }
            set
            {
                X *= value / _zoom;
                Y *= value / _zoom;
                _zoom = value;
                TB_zoom.Text = (int)(_zoom * 100) + "%";
                pop_zoom.IsOpen = true;
                NeedToClose = true;
                DrawSearchItems_Anim(g_zoom, 0.7, 0);

                showWidth = (int)(Zoom * JPGWidth);
                showHeight = (int)(Zoom * JPGHeight);
                C_Pic.Width = JPGWidth * Zoom;
                C_Pic.Height = JPGHeight * Zoom;
                this.translation.ScaleX = this.translation.ScaleY = initialScale = 1;
            }
        }
        public double X { get; set; }//中心坐标
        public double Y { get; set; }//中心坐标
        double JPGWidth;
        double JPGHeight;
        int showWidth;
        int showHeight;
        DispatcherTimer dt;
        Thread t;
        double svwidth = 480.0;
        double svheight = 730.0;
        public PageMode1()
        {
            InitializeComponent();

            if (App.ScreenIsLock == true)
            {
                var btn_LockSrceen = ApplicationBar.MenuItems[2] as ApplicationBarMenuItem;
                btn_LockSrceen.Text = "解除屏幕锁定";
                BtnLock.Content = "解除屏幕锁定";
                if (App.pageorientation == PageOrientation.Portrait || App.pageorientation == PageOrientation.PortraitUp || App.pageorientation == PageOrientation.PortraitDown)
                {
                    this.SupportedOrientations = SupportedPageOrientation.Portrait;
                }
                else
                {
                    this.SupportedOrientations = SupportedPageOrientation.Landscape;
                }
            }

            dt = new DispatcherTimer();
            dt.Interval = TimeSpan.FromSeconds(0.1);
            dt.Tick += new EventHandler(dt_Tick); 
            dt.Start();
            t = new Thread(DrawNeed);
            t.Start();

            this.Loaded += new RoutedEventHandler(PageMode1_Loaded);
        }

        void PageMode1_Loaded(object sender, RoutedEventArgs e)
        {
            if (App.bitmap == null)
            {
            }
            else
            {
                JPGWidth = App.bitmap.PixelWidth;
                JPGHeight = App.bitmap.PixelHeight;
                Getsuitzoom();
                Mathing(); 
                SetAppBarEnable(true);
            }
        }

        void dt_Tick(object sender, EventArgs e)
        {
            Mathing();
        }
        void Mathing()
        {
            X = sv_main.HorizontalOffset + svwidth / 2;
            Y = sv_main.VerticalOffset + svheight / 2;

            //tb1.Text = X.ToString();
            //tb2.Text = Y.ToString();

            if (piclst.Count > 9)
            {
                int x = X > 1500 ? ((int)(X / 1000)) : 0;
                int y = Y > 1500 ? ((int)(Y / 1000)) : 0;
                List<int> temp = new List<int>();
                foreach (var item in piclst)
                {
                    if (item.Key / 1000 > x + 1 || item.Key / 1000 < x - 1 || item.Key % 1000 > y + 1 || item.Key % 1000 < y - 1)
                    {
                        temp.Add(item.Key);
                        item.Value.Source = null;
                        C_Pic.Children.Remove(item.Value);
                    }
                }
                foreach (var t in temp)
                    piclst.Remove(t);
            }

            GetNeed();
        }

        Dictionary<int, Image> piclst = new Dictionary<int, Image>();
        List<int> NeedToUpload = new List<int>();
        List<picdata> PicDatalst = new List<picdata>();
        class picdata
        {
            int key;
            bool flag = false;
            int[] data;
        }
        void ReDraw()
        {
            piclst = new Dictionary<int, Image>(); 
            NeedToUpload = new List<int>();
            for (int i = 0; i < C_Pic.Children.Count; i++)
            {
                //if (C_Pic.Children[i] is )
                (C_Pic.Children[i] as Image).Source = null;
                C_Pic.Children.RemoveAt(i--);
            }
            Mathing();
        }
        void GetNeed()
        {
            NeedToUpload.Clear();
            int x = X > 1500 ? ((int)(X / 1000 - 1)) * 1000 : 0;
            int _y = Y > 1500 ? ((int)(Y / 1000 - 1)) * 1000 : 0;
            int y = _y;

            showWidth = (int)(Zoom * JPGWidth);
            showHeight = (int)(Zoom * JPGHeight);

            while (x < showWidth && x < X + 1500)
            {
                int w = (showWidth - x) < 1000 ? (showWidth - x) : 1000;
                while (y < showHeight && y < Y + 1500)
                {
                    int h = (showHeight - y) < 1000 ? (showHeight - y) : 1000;
                    Image img = new Image();
                    NeedToUpload.Add(x + y / 1000);
                    y += h;
                }
                y = _y;
                x += w;
            }
        }
        void DrawNeed()
        {
            while (true)
            {
                if (NeedToUpload.Count > 0)
                {
                    var item = NeedToUpload.First();
                    NeedToUpload.Remove(item);
                    int x = item / 1000 * 1000;
                    int y = item % 1000 * 1000;
                    if (piclst.ContainsKey(x + y / 1000)) continue;
                    int w = (showWidth - x) < 1000 ? (showWidth - x) : 1000;
                    int h = (showHeight - y) < 1000 ? (showHeight - y) : 1000;
                    double zoom = Zoom;
                    int[] thisdata = GetOnePicData(App.bitmap, w, h, (x / Zoom), (y / Zoom), Zoom);
                    if (zoom != Zoom) continue;
                    Dispatcher.BeginInvoke(() =>
                    {
                        if (piclst.ContainsKey(x + y / 1000)) return;
                        Image img = new Image();
                        WriteableBitmap picout = new WriteableBitmap(w, h);
                        thisdata.CopyTo(picout.Pixels, 0);
                        img.Source = picout;
                        Canvas.SetTop(img, y - y / 1000);
                        Canvas.SetLeft(img, x - x / 1000);
                        piclst.Add(x + y / 1000, img);
                        C_Pic.Children.Add(img);
                    });
                }
                else
                    Thread.Sleep(100);
            }
        }

        int[] GetOnePicData(WriteableBitmap picsourse, int weight, int height, double X, double Y, double zoom)
        {
            int[] picout = new int[weight * height];
            for (int i = 0; i < picout.Length; i++)
            {
                double x = ((i % weight) / zoom);
                double y = ((i / weight) / zoom);
                picout[i] = picsourse.Pixels[(int)(Y + y) * picsourse.PixelWidth + (int)(X + x)];
            }
            return picout;
        }

        WriteableBitmap GetOnePic(WriteableBitmap picsourse, int weight, int height, double X, double Y)
        {
            WriteableBitmap picout = new WriteableBitmap(weight, height);
            for (int i = 0; i < picout.Pixels.Length; i++)
            {
                double x = ((i % picout.PixelWidth) / Zoom);
                double y = ((i / picout.PixelWidth) / Zoom);
                picout.Pixels[i] = picsourse.Pixels[(int)(Y + y) * picsourse.PixelWidth + (int)(X + x)];
            }
            return picout;
        }

        private void Click_OnCamera(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/AblumList.xaml", UriKind.RelativeOrAbsolute));
        }

        private void C_Pic_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if (Zoom == 1)
            {
                Zoom = FitZoom;
                ReDraw();
            }
            else
            {
                Zoom = 1;
                ReDraw();
            }
            //DrawPic();
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            this.NavigationService.Navigate(new Uri("/AblumList.xaml", UriKind.Relative));
            base.OnBackKeyPress(e);
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            for (int i = 0; i < C_Pic.Children.Count; i++)
            {
                (C_Pic.Children[i] as Image).Source = null;
                C_Pic.Children.RemoveAt(i--);
            }
            base.OnNavigatedFrom(e);
        }

        double FitZoom, HeightFitZoom, WidthFitZoom;
        void Getsuitzoom()
        {
            HeightFitZoom = svheight / JPGHeight;
            WidthFitZoom = svwidth / JPGWidth;
            FitZoom = JPGWidth / JPGHeight > svwidth / svheight ? WidthFitZoom : HeightFitZoom;
            Zoom = FitZoom;
        }

        double initialScale;
        private void GestureListener_PinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            initialScale = this.translation.ScaleX;
            pop_zoom.IsOpen = true;
            NeedToClose = false;
            TB_zoom.Text = (int)(_zoom * 100) + "%";
            DrawSearchItems_Anim(g_zoom, 0.7, 0.7);
        }

        private void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
        {
            this.translation.ScaleX = this.translation.ScaleY = initialScale * e.DistanceRatio;
            TB_zoom.Text = (int)(_zoom * e.DistanceRatio * 100) + "%";
        }

        private void GestureListener_PinchCompleted(object sender, PinchGestureEventArgs e)
        {
            Zoom = Zoom * e.DistanceRatio;
            ReDraw();
            //DrawPic();
        }

        private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            App.pageorientation = e.Orientation;
            if (App.pageorientation == PageOrientation.Portrait || App.pageorientation == PageOrientation.PortraitUp || App.pageorientation == PageOrientation.PortraitDown)
            {
                svwidth = 480.0;
                svheight = 730.0;
            }
            else
            {
                svwidth = 730.0;
                svheight = 480.0;
            }
            if (App.bitmap == null)
                return;
            Getsuitzoom();
            ReDraw();
        }
        
        private void Click_ToMain(object sender, EventArgs e)
        {
            App.ViewMode = 0;
            App.ToViewPage(this);
        }

        public void DrawSearchItems_Anim(UIElement uielement, double Start, double End, string attrname = "(Opacity)")
        {
            //实例化Storyboard
            Storyboard storyboard = new Storyboard();
            DoubleAnimation doubleAnimationX = new DoubleAnimation();
            doubleAnimationX.Duration = new Duration(TimeSpan.FromMilliseconds(2000));
            doubleAnimationX.EasingFunction = new SineEase();
            doubleAnimationX.From = Start;
            doubleAnimationX.To = End;
            Storyboard.SetTarget(doubleAnimationX, uielement);
            Storyboard.SetTargetProperty(doubleAnimationX, new PropertyPath(attrname));
            storyboard.Children.Add(doubleAnimationX);
            storyboard.Completed += new EventHandler(storyboard_Completed);
            storyboard.Begin();
        }
        bool NeedToClose = true;
        void storyboard_Completed(object sender, EventArgs e)
        {
            if (NeedToClose)
                pop_zoom.IsOpen = false;
        }

        private void sv_main_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            if (!e.IsInertial)
            {
                dt.Stop();
                Mathing();
            }
        }

        private void sv_main_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            //if (Zoom > suitzoom)
            //{
            dt.Start();
            //}
        }

        private void Click_SetZoom(object sender, EventArgs e)
        {
            OpenZoomSet();
            TbZoomSet.Focus();
        }

        private void Click_LockSrceen(object sender, EventArgs e)
        {
            LockSrceen();
        }

        void LockSrceen()
        {
            var btn_LockSrceen = ApplicationBar.MenuItems[2] as ApplicationBarMenuItem;
            if (!App.ScreenIsLock)
            {
                btn_LockSrceen.Text = "解除屏幕锁定";
                BtnLock.Content = "解除屏幕锁定";
                App.ScreenIsLock = true;
                if (App.pageorientation == PageOrientation.Portrait || App.pageorientation == PageOrientation.PortraitUp || App.pageorientation == PageOrientation.PortraitDown)
                {
                    this.SupportedOrientations = SupportedPageOrientation.Portrait;
                }
                else
                {
                    this.SupportedOrientations = SupportedPageOrientation.Landscape;
                }
            }
            else
            {
                btn_LockSrceen.Text = "锁定屏幕方向";
                BtnLock.Content = "锁定屏幕方向";
                App.ScreenIsLock = false;
                this.SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;
            }
        }

        private void GestureListener_Hold(object sender, Microsoft.Phone.Controls.GestureEventArgs e)
        {
            OpenZoomSet();
        }

        void OpenZoomSet()
        {
            pop_zoomSet.IsOpen = true;
        }

        void BtnWidthFit_Click(object sender, RoutedEventArgs e)
        {
            Zoom = WidthFitZoom;
            ReDraw();
            pop_zoomSet.IsOpen = false;
        }
        void BtnHeightFit_Click(object sender, RoutedEventArgs e)
        {
            Zoom = HeightFitZoom;
            ReDraw();
            pop_zoomSet.IsOpen = false;
        }
        void BtnScreenFit_Click(object sender, RoutedEventArgs e)
        {
            Zoom = FitZoom;
            ReDraw();
            pop_zoomSet.IsOpen = false;
        }
        void BtnFull_Click(object sender, RoutedEventArgs e)
        {
            Zoom = 1;
            ReDraw();
            pop_zoomSet.IsOpen = false;
        }

        List<ApplicationBarIconButton> AppBtn;
        void ChangeAppBarToText()
        {
            AppBtn = new List<ApplicationBarIconButton>();
            foreach (var btn in ApplicationBar.Buttons)
            {
                AppBtn.Add(btn as ApplicationBarIconButton);
            }
            ApplicationBar.Buttons.Clear();
            ApplicationBarIconButton BtnOk = new ApplicationBarIconButton(new Uri("/Icons/appbar.check.rest.png", UriKind.Relative));
            BtnOk.Text = "确定";
            BtnOk.Click += BtnOk_Click;
            ApplicationBar.Buttons.Add(BtnOk);
            ApplicationBarIconButton BtnClose = new ApplicationBarIconButton(new Uri("/Icons/appbar.close.rest.png", UriKind.Relative));
            BtnClose.Text = "取消";
            BtnClose.Click += BtnClose_Click;
            ApplicationBar.Buttons.Add(BtnClose);
            ApplicationBar.IsMenuEnabled = false;
        }
        void ChangeAppBarToApp()
        {
            if (AppBtn != null)
            {
                ApplicationBar.Buttons.Clear();
                foreach (var btn in AppBtn)
                {
                    ApplicationBar.Buttons.Add(btn);
                }
                AppBtn = null;
            }
            ApplicationBar.IsMenuEnabled = true;
        }

        void BtnClose_Click(object sender, EventArgs e)
        {
            BtnFull.Focus();
        }

        void BtnOk_Click(object sender, EventArgs e)
        {
            string tmp = TbZoomSet.Text;
            try
            {
                Zoom = Convert.ToDouble(tmp) / 100;
                ReDraw();
                pop_zoomSet.IsOpen = false;
                TbZoomSet.Text = "";
            }
            catch
            {
                var messagePrompt = new MessagePrompt
                {
                    Title = "警告！",
                    Message = "请输入数字！"
                };
                messagePrompt.Show();
            }
        }

        private void TbZoomSet_GotFocus(object sender, RoutedEventArgs e)
        {
            ChangeAppBarToText();
        }

        private void TbZoomSet_LostFocus(object sender, RoutedEventArgs e)
        {
            ChangeAppBarToApp();
        }


        private void C_Pic_MouseEnter(object sender, MouseEventArgs e)
        {
            if (pop_zoomSet.IsOpen == true)
                pop_zoomSet.IsOpen = false;
        }

        private void BtnLock_Click(object sender, RoutedEventArgs e)
        {
            LockSrceen();
        }

        private void Click_About(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/PageAbout.xaml", UriKind.Relative));
        }

        private void Click_Next(object sender, EventArgs e)
        {
            SetAppBarEnable(false);
            if (App.ShowNextOrPrevious(this))
            {
                JPGWidth = App.bitmap.PixelWidth;
                JPGHeight = App.bitmap.PixelHeight;
                Getsuitzoom();
                ReDraw();
            }
            SetAppBarEnable(true);
        }

        private void Click_Previous(object sender, EventArgs e)
        {
            SetAppBarEnable(false);
            if (App.ShowNextOrPrevious(this, -1))
            {
                JPGWidth = App.bitmap.PixelWidth;
                JPGHeight = App.bitmap.PixelHeight;
                Getsuitzoom();
                ReDraw();
            }
            SetAppBarEnable(true);
        }

        void SetAppBarEnable(bool b)
        {
            this.ApplicationBar.IsMenuEnabled = b;
            (this.ApplicationBar.Buttons[0] as ApplicationBarIconButton).IsEnabled = App.PictureNum == 0 ? false : b;
            (this.ApplicationBar.Buttons[2] as ApplicationBarIconButton).IsEnabled = App.PictureNum == App.SelectedAlbum.Count - 1 ? false : b;
        }
    }
}